﻿using System;
using System.Collections.Generic;

namespace DigitalQuran.Numerology
{
    /// <summary>
    /// Configuration Options for Numerology System
    /// </summary>
    public sealed class NumerologyOptions
    {
        /// <summary>
        /// Gets or sets whether to add letter number in adjusting letter value
        /// </summary>
        public bool AddLetterNumberInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add word number in adjusting letter value
        /// </summary>
        public bool AddWordNumberInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add verse number in adjusting letter value
        /// </summary>
        public bool AddVerseNumberInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter number in adjusting letter value
        /// </summary>
        public bool AddChapterNumberInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add letter distance in adjusting letter value
        /// </summary>
        public bool AddLetterDistanceInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add word distance in adjusting letter value
        /// </summary>
        public bool AddWordDistanceInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add verse distance in adjusting letter value
        /// </summary>
        public bool AddVerseDistanceInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter distance in adjusting letter value
        /// </summary>
        public bool AddChapterDistanceInLetter { get; set; }

        /// <summary>
        /// Gets or sets whether to add word number in adjusting word value
        /// </summary>
        public bool AddWordNumberInWord { get; set; }

        /// <summary>
        /// Gets or sets whether to add verse number in adjusting word value
        /// </summary>
        public bool AddVerseNumberInWord { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter number in adjusting word value
        /// </summary>
        public bool AddChapterNumberInWord { get; set; }

        /// <summary>
        /// Gets or sets whether to add word distance in adjusting word value
        /// </summary>
        public bool AddWordDistanceInWord { get; set; }

        /// <summary>
        /// Gets or sets whether to add verse distance in adjusting word value
        /// </summary>
        public bool AddVerseDistanceInWord { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter distance in adjusting word value
        /// </summary>
        public bool AddChapterDistanceInWord { get; set; }

        /// <summary>
        /// Gets or sets whether to add verse number in adjusting verse value
        /// </summary>
        public bool AddVerseNumberInVerse { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter number in adjusting verse value
        /// </summary>
        public bool AddChapterNumberInVerse { get; set; }

        /// <summary>
        /// Gets or sets whether to add verse distance in adjusting verse value
        /// </summary>
        public bool AddVerseDistanceInVerse { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter distance in adjusting verse value
        /// </summary>
        public bool AddChapterDistanceInVerse { get; set; }

        /// <summary>
        /// Gets or sets whether to add chapter number in adjusting chapter value
        /// </summary>
        public bool AddChapterNumberInChapter { get; set; }

        /// <summary>
        /// Adjust value of letter according to the options
        /// </summary>
        /// <param name="word">Word containing letter</param>
        /// <param name="letterIndex">Index of letter in word</param>
        /// <returns>Returns adjusted value of letter</returns>
        public int AdjustLetterValue(Word word, int letterIndex)
        {
            int result = 0;

            if (AddLetterNumberInLetter && (letterIndex >= 0) && (letterIndex < word.Letters.Count))
                result += word.Letters[letterIndex].NumberInWord;

            if (AddWordNumberInLetter)
                result += word.NumberInVerse;

            if (AddVerseNumberInLetter)
                result += word.Verse.NumberInChapter;

            if (AddChapterNumberInLetter)            
                result += word.Verse.Chapter.GlobalNumber;

            if (AddLetterDistanceInLetter && (letterIndex >= 0) && (letterIndex < word.Letters.Count))
                result += word.Letters[letterIndex].DistanceToPrevious.DistanceFromLetter;

            if (AddWordDistanceInLetter && (letterIndex >= 0) && (letterIndex < word.Letters.Count))
                result += word.Letters[letterIndex].DistanceToPrevious.DistanceFromWord;

            if (AddVerseDistanceInLetter && (letterIndex >= 0) && (letterIndex < word.Letters.Count))            
                result += word.Letters[letterIndex].DistanceToPrevious.DistanceInVerse;

            if (AddChapterDistanceInLetter && (letterIndex >= 0) && (letterIndex < word.Letters.Count))                                            
                    result += word.Letters[letterIndex].DistanceToPrevious.DistanceInChapter;                            

            return result;
        }

        /// <summary>
        /// Adjust value of word
        /// </summary>
        /// <param name="word">Word whose value to adjust</param>
        /// <returns>Returns adjusted value of word</returns>
        public int AdjustWordValue(Word word)
        {
            int result = 0;

            if (AddWordNumberInWord)            
                result += word.NumberInVerse;            
            if (AddVerseNumberInWord)            
                result += word.Verse.NumberInChapter;            
            if (AddChapterNumberInWord)            
                result += word.Verse.Chapter.GlobalNumber;            
            if (AddWordNumberInWord)            
                result += word.DistanceToPrevious.DistanceFromWord;            
            if (AddVerseDistanceInWord)            
                result += word.DistanceToPrevious.DistanceInVerse;            
            if (AddChapterDistanceInWord)            
                result += word.DistanceToPrevious.DistanceInChapter;            

            return result;
        }

        /// <summary>
        /// Adjust value of verse
        /// </summary>
        /// <param name="verse">Verse whose value to adjust</param>
        /// <returns>Returns adjusted value of verse</returns>
        public int AdjustVerseValue(Verse verse)
        {
            int result = 0;

            if (AddVerseNumberInVerse)            
                result += verse.NumberInChapter;            
            if (AddChapterNumberInVerse)            
                result += verse.Chapter.GlobalNumber;            
            if (AddVerseDistanceInVerse)            
                result += verse.DistanceToPrevious.DistanceInVerse;            
            if (AddChapterDistanceInVerse)            
                result += verse.DistanceToPrevious.DistanceInChapter;            

            return result;
        }

        /// <summary>
        /// Adjust value of chapter
        /// </summary>
        /// <param name="chapter">Chapter whose value to adjust</param>
        /// <returns>Returns adjusted value of chapter</returns>
        public int AdjustChapterValue(Chapter chapter)
        {           
            int result = 0;            

            if (AddChapterNumberInChapter)       
                result += chapter.GlobalNumber;            

            return result;
        }

        public void Reset() {
            AddChapterDistanceInLetter = false;
            AddChapterDistanceInVerse = false;
            AddChapterDistanceInWord = false;
            AddChapterNumberInChapter = false;
            AddChapterNumberInLetter = false;
            AddChapterNumberInVerse = false;
            AddChapterNumberInWord = false;
            AddLetterDistanceInLetter = false;
            AddLetterNumberInLetter = false;
            AddVerseDistanceInLetter = false;
            AddVerseDistanceInVerse = false;
            AddVerseDistanceInWord = false;
            AddVerseNumberInLetter = false;
            AddVerseNumberInVerse = false;
            AddVerseNumberInWord = false;
            AddWordDistanceInLetter = false;
            AddWordDistanceInWord = false;
            AddWordNumberInLetter = false;
            AddWordNumberInWord = false;
        }
    }
}